package com.qw.flutter.nativedialog;

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/**
 * FlutterNativeDialogPlugin
 * 方法回调顺序
 * 1、onAttachedToEngine
 * 2、onAttachedToActivity
 * 3、maybeStartListening()
 * 4、onDetachedFromActivity
 * 5、onDetachedFromEngine
 */
public class FlutterDialogPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
    private static final String TAG = "FlutterDialogPlugin";

    /**
     * 显示原生加载框
     */
    private static final String SHOW_LOADING = "showLoading";
    private static final String SHOW_HTTP_LOADING = "showHttpLoading";

    /**
     * 隐藏原生加载框
     */
    private static final String HIDE_LOADING = "hideLoading";
    private static final String HIDE_HTTP_LOADING = "hideHttpLoading";
    /**
     * 推送弹窗关闭事件到flutter
     */
    private static final String BACK_BUTTON_CLOSE_DIALOG_EVENT = "backButtonCloseDialogEvent";
    private static final String FIELD_TAG = "tag";
    private static final String FIELD_MSM = "msg";
    private static final String FIELD_CAN_CANCEL = "canCancel";
    private static final String FIELD_STYLE = "style";

    private @Nullable
    FlutterPluginBinding flutterPluginBinding;

    private MethodChannel channel;

    private DialogManager dialogManager;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        Log.i(TAG, "onAttachedToEngine");
        this.flutterPluginBinding = binding;
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        Log.i(TAG, "onDetachedFromEngine");
        this.flutterPluginBinding = null;
    }

    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
        Log.i(TAG, "onAttachedToActivity");
        if (flutterPluginBinding != null) {
            maybeStartListening(binding.getActivity(),
                    flutterPluginBinding.getBinaryMessenger());
        }
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
        Log.i(TAG, "onDetachedFromActivityForConfigChanges");
        onDetachedFromActivity();
    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
        Log.i(TAG, "onReattachedToActivityForConfigChanges");
        onAttachedToActivity(binding);
    }

    @Override
    public void onDetachedFromActivity() {
        Log.i(TAG, "onDetachedFromActivity");
        stopListening();
    }

    /**
     * 应用启动时会调用该方法注册
     *
     * @param activity
     * @param messenger
     */
    private void maybeStartListening(Activity activity, BinaryMessenger messenger) {
        Log.i(TAG, "maybeStartListening()");
        stopListening();
        channel = new MethodChannel(messenger, "flutter_nativedialog_plugin");
        channel.setMethodCallHandler(this);
        dialogManager = new DialogManager(activity, this);
    }

    private void stopListening() {
        if (channel != null) {
            channel.setMethodCallHandler(null);
        }
        if (dialogManager != null) {
            dialogManager.dismissAll();
        }
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if (SHOW_HTTP_LOADING.equals(call.method)) {
            //显示http加载框
            String msg = "";
            String tag = null;
            boolean canCancel = true;
            String loadingStyle = null;
            if (call.hasArgument(FIELD_MSM)) {
                msg = call.argument(FIELD_MSM);
            }
            if (call.hasArgument(FIELD_TAG)) {
                tag = call.argument(FIELD_TAG);
            }
            if (call.hasArgument(FIELD_CAN_CANCEL)) {
                canCancel = toBoolValue((Boolean) call.argument(FIELD_CAN_CANCEL), true);
            }

            if (call.hasArgument(FIELD_STYLE)) {
                loadingStyle = call.argument(FIELD_STYLE);
            }
            if (loadingStyle == null) {
                loadingStyle = "ThreeBounce";
            }

            if (tag != null) {
                dialogManager.showHttpDialog(tag, msg, loadingStyle, canCancel);
            }

            result.success(null);
        } else if (HIDE_HTTP_LOADING.equals(call.method)) {
            //隐藏http加载框
            String tag = null;
            if (call.hasArgument(FIELD_TAG)) {
                tag = call.argument(FIELD_TAG);
            }
            if (tag != null) {
                dialogManager.dismissHttpDialog(tag);
            }
            result.success(null);
        } else if (SHOW_LOADING.equals(call.method)) {
            //显示通用加载框
            String msg = "";
            boolean canCancel = true;
            String loadingStyle = null;
            if (call.hasArgument(FIELD_MSM)) {
                msg = call.argument(FIELD_MSM);
            }

            if (call.hasArgument(FIELD_CAN_CANCEL)) {
                canCancel = toBoolValue((Boolean) call.argument(FIELD_CAN_CANCEL), true);
            }

            if (call.hasArgument(FIELD_STYLE)) {
                loadingStyle = call.argument(FIELD_STYLE);
            }
            if (loadingStyle == null) {
                loadingStyle = "ThreeBounce";
            }

            dialogManager.showCommonDialog(msg, loadingStyle, canCancel);
            result.success(null);
        } else if (HIDE_LOADING.equals(call.method)) {
            //隐藏通用加载框
            dialogManager.dismissCommonDialog();
            result.success(null);
        } else {
            result.notImplemented();
        }
    }

    private boolean toBoolValue(Boolean number, boolean defValue) {
        return number != null ? number : defValue;
    }

    /**
     * 通知flutter有弹窗通过物理按钮关闭
     *
     * @param tag 关闭的弹窗对应的tag
     */
    public void onBackButtonCloseDialogEvent(String tag) {
        if (channel != null) {
            channel.invokeMethod(BACK_BUTTON_CLOSE_DIALOG_EVENT, tag);
        }
    }


}
